class UsersController < ApplicationController  
 
  include AuthenticatedSystem
  # render new.rhtml
  def new
  end

  def create
    cookies.delete :auth_token
    # protects against session fixation attacks, wreaks havoc with 
    # request forgery protection.
    # uncomment at your own risk
    # reset_session
    problematical_sources = check_source_user_relations(params[:source_user], params[:source_pass])
    @user = User.new(params[:user])
    
    if @user.valid?
      if problematical_sources.size() == 0 && @user.save
        create_source_user_relations(params[:source_user], params[:source_pass])
        self.current_user = @user
        redirect_back_or_default('/')
        flash[:notice] = "Thanks for signing up!"
      else
        problematical_sources.each do |s|
          @user.errors.add(s + ": user password combination")
        end
        render :action => 'new'
      end
    else
      @user.save #filling in the other errors
      problematical_sources.each do |s|
        @user.errors.add(s + ": user password combination")
      end
      render :action => 'new'
     end
  end

  def edit
    @user = User.find(params[:id])
    if !params[:source_user] or !params[:source_pass]
      params[:source_user] = Hash.new
      params[:source_pass] = Hash.new
      Source.find(:all).each do |s|
        su = SourceUser.find(:first, :conditions => {:user_id => @user.id, :source_id => s.id})
        params[:source_user][s.name] = su ? su.username : ""
        params[:source_pass][s.name] = su ? su.password : ""
      end
    end
  end

  def update
    @user = User.find(params[:id])
    pass_match = @user.authenticated?(params[:old_password])
    problematical_sources = check_source_user_relations(params[:source_user], params[:source_pass])
    if @user.update_attributes(params[:user]) and pass_match and problematical_sources.size() == 0
      SourceUser.destroy_all :user_id => @user.id
      create_source_user_relations(params[:source_user], params[:source_pass])
      redirect_back_or_default('/')
      flash[:notice] = "User info successfully updated!"
    else
      if !pass_match
        @user.errors.add("current password")
      end
      problematical_sources.each do |s|
        @user.errors.add(s + ": user password combination")
      end
      render :action => 'edit'
    end
  end
  
  private
  
  def create_source_user_relations(source_users, source_passes)
    source_users.each_pair do |k, v|
      s = Source.find_by_name(k)
      new_source_user = SourceUser.new
      new_source_user.user = @user
      new_source_user.source = s
      new_source_user.password = source_passes[k]
      new_source_user.username = v
      new_source_user.save
    end
  end
  
  def check_source_user_relations(source_users, source_passes)
    invalid_sources = []
    source_users.each_pair do |k, v|
      s = Source.find_by_name(k)
      new_source_user = SourceUser.new
      new_source_user.user_id = 1 #mock user in fact this is not used; only validation check is done
      new_source_user.source = s
      new_source_user.password = source_passes[k]
      new_source_user.username = v
      invalid_sources << s.name unless new_source_user.valid?
    end
    invalid_sources
  end
end
